/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = wtc_core.h                                        */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/13 by songbb                               */
/*******************************************************************/

#ifndef __WTC_CORE_H_
#define __WTC_CORE_H_

#include "frlist.h"
#include "frhash2.h"
#include "frstr.h"

#include "conntrack.h"
#include "module.h"
#include "frbyte_buffer.h"

typedef enum __em_tfmh_type {
    APM_WTC_TFMH_TYPE_ORIG = 1,
    APM_WTC_TFMH_TYPE_DOM,
    APM_WTC_TFMH_TYPE_WS
} WTC_tfmh_type;


typedef enum __em_tcb_type {
    APM_WTC_TCB_USER = 0,
    APM_WTC_TCB_TM,
    APM_WTC_TCB_TRAN,
    APM_WTC_TCB_WS,
    APM_WTC_TCB_UNSOL,
    APM_WTC_TCB_COMPOS_HDR,
    APM_WTC_TCB_COMPOS_FML,
    APM_WTC_TCB_TDOM,
    APM_WTC_TCB_TDOM_SEC,
    APM_WTC_TCB_ROUTE,
    APM_WTC_TCB_TDOM_TRAN,
    APM_WTC_TCB_TEST_TCM,
    APM_WTC_TCB_PKCS7_TCM,
    APM_WTC_TCB_QS_TCM,
    APM_WTC_TCB_PROP_TCM,
    APM_WTC_TCB_AAA_TCM,
    APM_WTC_TCB_CALLOUT,
    APM_WTC_TCB_TDOM_VALS,
    APM_WTC_TCB_CODESET_TCM,
    APM_WTC_TCB_META_TCM,
    APM_WTC_TCB_MAXDEF_TCM
} WTC_tcb_type;

typedef struct __st_wtc_tch_header
{
    WTC_tcb_type tcb_type;
    int len;
    int flags;
} WTC_tch_header;

/**
 * WTC协议通用包头
 */
typedef struct __st_wtc_header
{
    WTC_tfmh_type em_tfmh_type;         /* 数据包的组包类型，即tfmh中接口类型 */
    unsigned int ui_size;
    unsigned int ui_flags;
    unsigned int ui_uncmprs_sz;
} WTC_header;

/*
 * L7session_wtc 用于存放WTC私有的session数据，对应L7_session的p_session_private变量
 */
typedef struct __st_L7session_wtc
{
    char *p_service_name;
    char *p_client_domainid;
    char *p_service_domainid;

    struct timeval st_timestamp;
    u_int dst_ip;                       /* 预存的当前的服务端的IP */
    u_short dst_port;                   /* 预存的当前的服务端的端口 */

    int i_dom_proto_le13;

    char *p_default_encoding;
    char *p_codeset_encoding;
} L7session_wtc;

/**
 * 分片的状态
 */
typedef enum __em_fragment_state {
    APM_WTC_FRAGMENT_INIT,
    APM_WTC_FRAGMENT_NEED_NEXT_REQ_PACKET,
    APM_WTC_FRAGMENT_NEED_NEXT_RESP_PACKET
} WTC_fragment_state;

/**
 * WTC数据包结构体
 */
typedef struct __st_L7_wtc_packet
{
    WTC_fragment_state fragment_state;  /* 当前的分片状态 */
    Frbyte_Packet *p_st_packet;         /* 组包完成的数据 */
    WTC_tfmh_type em_tfmh_type;         /* 数据包的组包类型，即tfmh中接口类型 */
    int i_is_req;
    unsigned int ui_size;               /* 数据包长度（解压缩前）*/
    unsigned int ui_flags;
    unsigned int ui_uncmprs_sz;         /* 数据包长度（解压缩后）*/
    int i_use_old_protocol;

    unsigned int ui_len_to_read;        /* 还需要从下一个payload中读取多少个字节 */
    struct timeval st_timestamp_first;  /* 第一个请求的分片包的时间 */
    struct timeval st_timestamp_last;   /* 最后一个请求的分片包的时间 */
    unsigned long ul_skip_len;
} L7_wtc_packet;

typedef struct __st_L7_wtc_mbstring
{
    unsigned int ui_index;
    char *p_mbstring;
    unsigned int ui_mbstring_len;
} L7_wtc_mbstring;

/**
 * WTC交易信息
 */
typedef struct __st_L7_wtc_stmt
{
    unsigned int ui_diagnostic;
    unsigned int ui_tpurcode;
    unsigned int ui_errdetail;
    unsigned int ui_arg_count;
    struct timeval st_req_end_timestamp;
    struct timeval st_resp_start_timestamp;
    Frlist_header *p_list_mbstring;
    unsigned int ui_opcode;             /* 用于存储APM_WTC_TCB_TDOM时的opcode，主要用于记录commit和rollback动作 */
} L7_wtc_stmt;

/**
 * WTC私有结构体
 */
typedef struct __st_L7session_wtc_private
{
    L7session_wtc *p_st_sess;            /* session数据 */
    L7_wtc_stmt *p_st_wtc_stmt;          /* WTC当前进行中的交易 */
    L7_wtc_packet *p_st_wtc_packet;      /* 当前处理中的WTC数据包 */
    Frlist_header *p_report_comm;        /* 用于临时存储report的公共部分数据 */
    Frlist_header *p_report_req;         /* 用于临时存储report的请求部分数据 */
    L7_session *p_st_session;            /* 指向父级的L7_session结构体 */
} L7session_wtc_private;

int wtc_detect(Conntrack *p_st_conn
             , Apm_packet *p_st_packet);

int wtc_analyze(Conntrack *p_st_conn
              , Apm_packet *p_st_packet
              , Frhash_header *p_st_hash_report);

int wtc_session_destory(void *p_st_session_private_in);

#endif
